package com.sniper.web.action.error;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sniper.exception.DenyAccessException;
import com.sniper.exception.FrontNullException;
import com.sniper.utils.HttpRequestUtils;
import com.sniper.web.utils.ControllerUtils;
import com.sniper.web.utils.SystemConfigUtil;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 前台错误处理和后台分开
 * 如果他直接集成带有 @ModelAttribute的类会导致 @ModelAttribute方法的父级执行2遍，本身执行一遍这里执行一遍
 * 我觉得这应该和ControllerAdvice有关系
 * 这个类无论如何都会被调用
 * Created by suzhen on 2017/8/7.
 */
@ControllerAdvice
public class FrontErrorController extends ErrorController {


    private ModelAndView getMV(Exception ex) {

        //下面是前台所有大部分页面公共数据

        ModelAndView mv = new ModelAndView();
        baseHref.setBaseHref(getBasePath());
        // 无后缀域名
        baseHref.setWebUrl(getBasePath());
        mv.addObject("baseHref", baseHref);
        mv.addObject("ex", ex);
        mv.addObject("systemConfig", SystemConfigUtil.getSystemConfig());

        return mv;
    }

    private void ajax(Exception ex, HttpServletResponse response) throws IOException {
        if (HttpRequestUtils.isAjax(request)) {
            ControllerUtils.CallBackResult callBackResult = new ControllerUtils.CallBackResult();
            callBackResult.setMsg(ex.getMessage());
            PrintWriter printWriter = response.getWriter();
            ObjectMapper mapper = new ObjectMapper();
            printWriter.write(mapper.writeValueAsString(callBackResult));
            printWriter.flush();
            printWriter.close();
        }
    }

    /**
     * 处理前台找不到数据错误
     *
     * @param ex
     * @param response
     * @return
     * @throws IOException
     */
    @ExceptionHandler(value = FrontNullException.class)
    public Object FrontNullPointer(Exception ex, HttpServletResponse response) throws IOException {

        ajax(ex, response);
        ModelAndView mv = getMV(ex);
        mv.setViewName("/error/front-404.jsp");
        return mv;
    }


    /**
     * 处理全台无权限访问错误 500
     *
     * @param ex
     * @param response
     * @return
     * @throws IOException
     */
    @ExceptionHandler(value = DenyAccessException.class)
    public Object denyAccess(Exception ex, HttpServletResponse response) throws IOException {

        ajax(ex, response);
        ModelAndView mv = getMV(ex);
        mv.setViewName("/error/front-500.jsp");
        return mv;
    }

    /**
     * 全部默认错误处理
     *
     * @param ex
     * @param response
     * @return
     * @throws IOException
     */
    @ExceptionHandler(value = Exception.class)
    public Object exception(Exception ex, HttpServletResponse response) throws IOException {

        LOGGER.error("出错", ex);
        ajax(ex, response);
        ModelAndView mv = getMV(ex);
        mv.setViewName("/error/front-500.jsp");
        return mv;
    }

}
